/***************************************************************************
 创建者: 华磊
 开始时间: 2020.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2020.5.8 类的具体实现代码编写

 ***************************************************************************/
#include "ecatio.h"
#include <QDebug>
#include "ethercatVendorId.h"

//#include "messagelog.h"

EcatIo::EcatIo(E_DEVICE_PROTOCOL protocolIn, int aliasIn, int busIdIn)
{
    protocol=protocolIn;
    alias=aliasIn;
    busId=busIdIn;
    diCount=0;//物理
    doCount=0;//物理
    aiCount=0;//物理
    aoCount=0;//物理
    nodeId=0;

    memset( p_ioDi, 0, sizeof(p_ioDi) );
    memset( p_ioDo, 0, sizeof(p_ioDo) );
    memset( p_ioAi, 0, sizeof(p_ioAi) );
    memset( p_ioAo, 0, sizeof(p_ioAo) );
    memset( ioDo_one_output, 0, sizeof(ioDo_one_output) );

}

int EcatIo::initialProperty(unsigned int vendorIdIn,unsigned int productCodeIn,int diCountIn,int doCountIn,int aiCountIn,
                            int aoCountIn,int encoderCountIn,int controlCounterIn,int statusCounterIn)
{
    vendorId=vendorIdIn;
    productCode=productCodeIn;
    ethercatPdoDataOffsetInfo.ioDi.resize(diCountIn);
    ethercatPdoDataOffsetInfo.ioDo.resize(doCountIn);
    ethercatPdoDataOffsetInfo.ioAi.resize(aiCountIn);
    ethercatPdoDataOffsetInfo.ioAo.resize(aoCountIn);
    ethercatPdoDataOffsetInfo.ioEncoder.resize(encoderCountIn);
    ethercatPdoDataOffsetInfo.ioControlWorld.resize(controlCounterIn);
    ethercatPdoDataOffsetInfo.ioStatus.resize(statusCounterIn);
    diCount=diCountIn;
    doCount=doCountIn;
    aiCount=aiCountIn;
    aoCount=aoCountIn;
    encoderCount=encoderCountIn;
    controlCount=controlCounterIn;
    statusCount=statusCounterIn;
    switch (vendorIdIn) {
    case D_VENDOR_ID_LeiSai_IO:
    {
        switch (productCodeIn) {
        case D_VENDOR_ID_LeiSai_IO_EM06AXE1:
        {
            if(1==controlCount)
            {
                p_ioControlWorld[0]=0x41;//bit0 控制da是否输出，bit6-12控制控制１个AD通道的采样数量
            }
        }
            break;
        default:
            break;
        }
    }
        break;
    default:
        break;
    }
    return 1;
}

int EcatIo::getAlias()
{
    return alias;
}

int EcatIo::setCount(int diCounter,int doCounter,int aiCounter,int aoCounter)
{
    diCount=diCounter;
    doCount=doCounter;
    aiCount=aiCounter;
    aoCount=aoCounter;

    return 1;
}

void EcatIo::updateEthercatDo()
{
    switch( vendorId )
    {
        case D_VENDOR_ID_YODA://16BIT
        case D_VENDOR_ID_LeiSai_IO:
        {
            if(doCount>0 && doCount<=16)
            {
                for(int i=0; i<doCount; i++)
                {
                    setBitForShortArry( p_ioDo_short, i, ioDo_one_output[i] );
                }
            }
            if(doCount>16 && doCount<=32)
            {
                for(int i=0; i<doCount-16; i++)
                {
                    setBitForShortArry( &(p_ioDo_short[1]), i, ioDo_one_output[i+16] );
                }
            }
            if(doCount>32 && doCount<=48)
            {
                for(int i=0; i<doCount-32; i++)
                {
                    setBitForShortArry( &(p_ioDo_short[2]), i, ioDo_one_output[i+32] );
                }
            }
            if(doCount>48 && doCount<=64)
            {
                for(int i=0; i<doCount-48; i++)
                {
                    setBitForShortArry( &(p_ioDo_short[3]), i, ioDo_one_output[i+48] );
                }
            }


            break;
        }
    case D_VENDOR_ID_SHANGHAI_XINGYANG:
    {
        for(int i=0; i<doCount; i++)
        {
            setBitForShortArry( p_ioDo_short, i, ioDo_one_output[i] );
        }

        break;
    }
    case D_VENDOR_ID_TECHSERVO_C48IO:
    {
        if(D_VENDOR_ID_TECHSERVO_IO_80000800==productCode)
        {
            for(int i=0; i<doCount; i++)
            {
                setBitForShortArry( p_ioDo_short, i, ioDo_one_output[i] );
            }
        }

        break;
    }
        case D_VENDOR_ID_BURKMORE_IO:
        {
            for(int i=0; i<doCount; i++)
            {
                setBitForShortArry( p_ioDo_short, i, ioDo_one_output[i] );
            }

            break;
        }
        default:
        {
            for(int i=0; i<doCount; i++)
            {
                setBitForCharArry( p_ioDo, i, ioDo_one_output[i] );
            }
        }
    }

}

int EcatIo::setSdoList(QVector<SdoConfig> &sdoConfigListIn)
{
    sdoConfigList=sdoConfigListIn;
    return 1;
}

int EcatIo::getSdoList(QVector<SdoConfig> &sdoConfigListOut)
{
    sdoConfigListOut=sdoConfigList;
    return 1;
}

void EcatIo::setBitForCharArry(unsigned char* ptr, char bit, bool val)
{
    int highCount=bit>>3;
    int lowCount=bit&0x07;
    if(val){
        ptr[highCount] |= (0x01<<lowCount);
    }else{
        ptr[highCount] &= (~(0x01<<lowCount));
    }
}
bool EcatIo::getBitForCharArry(unsigned char* ptr, char bit)
{
    int highCount=bit>>3;
    int lowCount=bit&0x07;
    return (ptr[highCount] & (0x01<<lowCount))?true:false;
}


void EcatIo::setBitForShortArry(unsigned short* ptr, char bit, bool val)
{
    int highCount=bit>>4;
    int lowCount=bit&0x0f;
    if(val){
        ptr[highCount] |= (0x01<<lowCount);
    }else{
        ptr[highCount] &= (~(0x01<<lowCount));
    }
}
bool EcatIo::getBitForShortArry(unsigned short* ptr, char bit)
{
    int highCount=bit>>4;
    int lowCount=bit&0x0f;
    return (ptr[highCount] & (0x01<<lowCount))?true:false;
}

bool EcatIo::getDi(int index)
{
    switch( vendorId )
    {
        case D_VENDOR_ID_YODA://16BIT
        case D_VENDOR_ID_SHANGHAI_XINGYANG:
        case D_VENDOR_ID_LeiSai_IO:
        {
            if(index>diCount)
                return 0;

            if(index>0 && index<=16)
            {
               return getBitForShortArry(p_ioDi_short, index);
            }
            if(index>16 && index<=32)
            {
                return getBitForShortArry(&(p_ioDo_short[1]), index-16);
            }
            if(index>32 && index<=48)
            {
                return getBitForShortArry(&(p_ioDo_short[2]), index-32);
            }
            if(index>48 && index<=64)
            {
                return getBitForShortArry(&(p_ioDo_short[3]), index-48);
            }
            break;
        }
        case D_VENDOR_ID_TECHSERVO_C48IO:
        {
            if(D_VENDOR_ID_TECHSERVO_IO_80000800==productCode)
            {
                if(index>diCount)
                    return 0;
                return getBitForShortArry(p_ioDi_short, index);
            }

            break;
        }
        case D_VENDOR_ID_BURKMORE_IO:
        {
            if(index>diCount)
                return 0;
            return getBitForShortArry(p_ioDi_short, index);
            break;
        }
        default:
        {
            if(index>diCount)
                return 0;
            return getBitForCharArry(p_ioDi, index);
        }
    }
}

float EcatIo::getAi(int index)
{
    if(index>aiCount)
        return 0.0;
   return p_ioAi[index];
}

void  EcatIo::setDo(int index, bool val)
{
    if(index>doCount)
        return;
    ioDo_one_output[index]=val;
}

void  EcatIo::setAo(int index, float val)
{
    if(index>aoCount)
        return;
    p_ioAo[index]=val;
}

bool  EcatIo::getDo(int index)
{
    if(index>doCount)
        return 0;
    return ioDo_one_output[index];
}

float EcatIo::getAo(int index)
{
    if(index>aoCount)
        return 0.0;
    return p_ioAo[index] ;
}

int EcatIo::getEncoderValue(int index)
{
    if(index>encoderCount)
        return 0;
    return p_ioEncoder[index] ;
}

int EcatIo::getEncoderValue(std::vector<int> &encoderValueOut)
{
    encoderValueOut.clear();
    for(int i=0;i<encoderCount;i++)
    {
        encoderValueOut.push_back(p_ioEncoder[i]);
    }

    return 1;
}



